#######################################################
# Example of PingPong coupled DEVS using DEVS player
# Author: moonho.hwang@gmail.com
#   Date: Oct.19.2011
#######################################################
from XSY.DEVS.Simulatable import *
from XSY.DEVS.CoupledDEVS import *
from XSY.DEVS.SimEngine import SimEngine

class Player(DEVS):
   '''atomic DEVS model for a ping-pong player'''
   def __init__(self, name, init, parent=None):
      '''constructor'''
      DEVS.__init__(self, name, parent)
      self.initphase = init
      self.addInputPorts("?r")
      self.addOutputPorts("!s")

   def delta_0(self):
      '''reset function'''
      self.phase = self.initphase
      if self.phase == 'W':
         self.sigma = float('inf')
      else:
	 self.sigma = 1.5
     
   def ta(self):
      '''time advanced function'''
      return self.sigma

   def delta_ext(self, x=None):
      '''external transition function'''
      if self.phase == 'W': 
         self.phase = 'S'
         self.sigma = 1.5
      else:
	      self.sigma = self.timeRemaining() 

   def _lambda(self):
      '''output function'''
      if self.phase == 'S':
         return PortValue(self.OP["!s"])

   def delta_int(self):
      '''internal transition function'''
      if self.phase == 'S':
         self.phase = 'W'
         self.sigma = float('inf') 

   def state_to_s(self):
      '''state to string. This function is used for status display when runing simulation'''
      return str(self.phase)

   
if __name__ == '__main__':
   def inject_to_Player(md, JSONarg=None):
      '''injection function sending the input event ('?r') to md'''
      x = PortValue(md.IP['?r'])
      return (md,x) 

   md = Player(name = 'A', init='S') # step 1.
   engine = SimEngine(md, inject_to_Player) # step 2.
   engine.sfactor =1 # real time simulation, default is sfactor = float('inf')
   engine.runInteractiveMenu() # step 3.
